package com.etlmaster.executor.utils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import com.etlmaster.core.BeanFactory;
import com.etlmaster.core.DataSourceDefine;
import com.etlmaster.crypto.DesCipher;
import com.etlmaster.executor.utils.DataCollectionUtils;
import com.etlmaster.executor.utils.LogWriter;



/**
 * @author Wugf
 * @date 2016-11-10
 */
public class TeamDatasourceHolder {
	private static TeamDatasourceHolder instance;
	public TeamDatasourceHolder(List dbInfoList){
		instance=this;
		loadDataSourceDefs(dbInfoList);
	}
	
	public static TeamDatasourceHolder getInstance(){
		return instance;
	}
	
	private Map<String,DataSourceDefine> dsDefs = new HashMap<String,DataSourceDefine>();
	
	public Map<String, DataSourceDefine> getDsDefs() {
		return dsDefs;
	}

	public DataSourceDefine getDataSourceDefine(String dsName) {
		return dsDefs.get(dsName);
	}
	
	@SuppressWarnings("unchecked")
	private void loadDataSourceDefs(List dbInfoList){
		for(Object db:dbInfoList){
			
			DataSourceDefine def = new DataSourceDefine(DataCollectionUtils.getPropertyFromMap((Map) db,"dbname"),DataCollectionUtils.getPropertyFromMap((Map) db,"cnname"),
					DataCollectionUtils.getPropertyFromMap((Map) db,"driverclassname"),DataCollectionUtils.getDatasourceType(DataCollectionUtils.getPropertyFromMap((Map) db,"driverclassname")),
					DataCollectionUtils.getPropertyFromMap((Map) db,"url"),DataCollectionUtils.getPropertyFromMap((Map) db,"username"),
					DesCipher.decrypt(DataCollectionUtils.getPropertyFromMap((Map) db,"password")),
					DataCollectionUtils.getPropertyFromMap((Map) db,"jndiname"),DataCollectionUtils.getPropertyFromMap((Map) db,"alias"),"");
			dsDefs.put(def.getId(),def);
		}
	}
	
	private boolean isNull(String str){
		return str==null || str.length()==0;
	}
	
	
	public GenericBeanDefinition genDataSourceBeanDefinition(String url,String driverName,String username,String password){
		if(driverName.indexOf("hive")>0 || driverName.indexOf("transwarp")>0 || driverName.indexOf("spark")>0){
			return genHadoopDsBeanDefinition(driverName, url,username,password);
		}else{
			return genRdbDsBeanDefinition(driverName,  url, username, password);
		}
	}
	
	private GenericBeanDefinition genHadoopDsBeanDefinition(String driverName,String url,String username,String password){
		GenericBeanDefinition hadoopDriverBeanDef = new GenericBeanDefinition();
		hadoopDriverBeanDef.setBeanClassName(driverName);
		String dsType = DataCollectionUtils.getDatasourceType(driverName);
		BeanFactory.registerBeanDefinition(dsType+"-driver", hadoopDriverBeanDef, null);
		GenericBeanDefinition gbd = new GenericBeanDefinition();
		gbd.setBeanClass(org.springframework.jdbc.datasource.SimpleDriverDataSource.class);
		ConstructorArgumentValues args = new ConstructorArgumentValues();
		args.addIndexedArgumentValue(0, hadoopDriverBeanDef );
		args.addIndexedArgumentValue(1,url);
		args.addIndexedArgumentValue(2, username);
		args.addIndexedArgumentValue(3, password);
		gbd.setConstructorArgumentValues(args);
		return gbd;
	}
	
	private GenericBeanDefinition genRdbDsBeanDefinition(String driverName,String url,String username,String password){
		GenericBeanDefinition gbd = new GenericBeanDefinition();
		MutablePropertyValues mpv = new MutablePropertyValues();
		mpv.add("driverClassName", driverName);
		mpv.add("url", url);
		mpv.add("username", username);
		mpv.add("password", password);
		
		//先判断数据库有没有连接池 org.apache.commons.dbcp.BasicDataSource , org.springframework.jdbc.datasource.DriverManagerDataSource
		Class clz = null;
		try{
			clz = Class.forName("org.apache.commons.dbcp.BasicDataSource");
		}catch(Exception e){
			LogWriter.addLog("DEBUG","容器没有加载到连接池类：org.apache.commons.dbcp.BasicDataSource，使用的是直连可能会导致性能下降");
			clz = DriverManagerDataSource.class;
		}
		gbd.setBeanClass(clz);
		gbd.setPropertyValues(mpv);
		return gbd;
	}

}
